// Copyright (C) 2005-2008 Jae Stutzman (jaebird@gmail.com)
//
// This file is part of MrPodder.
//
// MrPodder is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// MrPodder is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with MrPodder.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.IO;
using ID3Lib;

namespace MediaHandler
{
	public class Mp3Tagger : TaggerBase
	{
		private const string Title = "TIT2";
		private const string Artist = "TPE1";
		private const string Album = "TALB";
		private const string Comment = "COMM";
		private const string Date = "TDAT";
		private const string Year = "TYER";
		private const string Time = "TIME";

		string artist;
		string title;
		string album;
		string comment;
		bool infoSet;

		private readonly string filename;
		private readonly MP3File mp3File = new MP3File();
		private TagModel tagModel;
		private int previousTagSize = 0;

		public Mp3Tagger(string filename)
		{
			this.filename = filename;

			MP3File file = new MP3File();
			try
			{
				tagModel = file.Read(filename);
				previousTagSize = tagModel.Header.HeaderSize + tagModel.Header.TagSize;
			}
			catch (Exception e)
			{
				tagModel = new TagModel();
			}
		}

		public override void GetInfo(ref string artist, ref string title, 
			ref string album, ref string comment, ref DateTime publishedDate)
		{
			int min = 0;
			int hour = 0;
			int day = 0;
			int month = 0;
			int year = 0;


			foreach(FrameBase frameBase in tagModel.Frames)
			{
				switch(frameBase.Tag)
				{
					case Title:
					{
						this.title = title = frameBase.ToString();
						break;
					}
					case Artist:
					{
						this.artist = artist = frameBase.ToString();
						break;
					}
					case Album:
					{
						this.album = album = frameBase.ToString();
						break;
					}
					case Time:
					{
						string time = frameBase.ToString();
						hour = Convert.ToInt32(time.Substring(0, 2));
						min = Convert.ToInt32(time.Substring(2, 2));
						break;
					}
					case Date:
					{
						string date = frameBase.ToString();
						day = Convert.ToInt32(date.Substring(0, 2));
						month = Convert.ToInt32(date.Substring(2, 2));
						break;
					}
					case Year:
					{
						year = Convert.ToInt32(frameBase.ToString());
						break;
					}
					case "TCOM":
					{
						break;
					}
					case "TCON":
					{
						// content type (genere)
						break;
					}
					case "TRCK":
					{
						// track number
						break;
					}
					case "USLT":
					{
						// lyrics
						break;
					}
					case Comment:
					{
						FrameLCText lcFrame = (FrameLCText)(frameBase);
						this.comment = comment = lcFrame.Text;
						//TODO: add --> lcFrame.Language;
						break;
					}
					case"APIC":
					{
						// picture
						break;
					}
				}
			}
			
			if (year > 0 && month > 0 && day > 0)
			{
				publishedDate = new DateTime(year, month, day, hour, min, 0);
				//publishDate = dateTime.ToString("r");
			}
		}

		public override void SetInfo(string artist, string title, string album, string comment)
		{
			this.artist = artist == null ? string.Empty : artist;
			this.title = title == null ? string.Empty : title;
			this.album = album == null ? string.Empty : album;
			this.comment = comment == null ? string.Empty : comment;
			infoSet = true;
		}

		public override void CommitInfo()
		{
			if (infoSet)
			{
				// title
				FrameText frameTitle = new FrameText(Title);
				frameTitle.Text = title;
				tagModel.Frames.Add(frameTitle);

				// artist (speaker)
				FrameText frameArtist = new FrameText(Artist);
				frameArtist.Text = artist;
				tagModel.Frames.Add(frameArtist);

				// album (series)
				FrameText frameAlbum = new FrameText(Album);
				frameAlbum.Text = album;
				tagModel.Frames.Add(frameAlbum);

				// comment (summary)
				FrameLCText frameLCText = (FrameLCText)FrameFactory.Build(Comment);
				frameLCText.TextCode = TextCode.ASCII;
				frameLCText.Language = "eng";
				frameLCText.Contents = "";
				frameLCText.Text = comment;
				tagModel.Frames.Add(frameLCText);

				FileInfo info = new FileInfo(filename);
				DateTime publishDateTime = info.LastWriteTime;

				// year
				FrameText frameYear = new FrameText(Year);
				frameYear.Text = publishDateTime.Year.ToString();
				tagModel.Frames.Add(frameYear);

				// date
				FrameText frameDate = new FrameText(Date);
				frameDate.Text = publishDateTime.ToString("ddMM");
				tagModel.Frames.Add(frameDate);

				// time
				FrameText frameTime = new FrameText(Time);
				frameTime.Text = publishDateTime.ToString("HHmm");
				tagModel.Frames.Add(frameTime);

				mp3File.Write(filename, previousTagSize, tagModel);
				infoSet = false;
			}
		}

	}
}
